package com.xuecheng.gateway.filters;

import cn.hutool.log.Log;
import com.alibaba.fastjson.JSON;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URLEncoder;

/**
 * 全局过滤器
 *   1、交给容器管理
 *   2、实现两个接口
 *   3、实现内部的两个方法
 *   4、在filter方法中，完成核心业务逻辑
 */
@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {
    /**
     * 核心方法：完成登录校验
     *    exchange：请求上下文
     *      获取请求的对象和响应的对象
     *    chain：过滤器链
     *      放行，向下执行
     */

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //排除不需要验证的路径
        String path = request.getURI().getPath();
        log.info("请求的path={}",path);
        //判断是否需要进行验证
        if(path.contains("coursePub/preview") ||
                path.contains("auth/login") ||
                path.contains("basic/dictionary") ||
                path.contains("category/tree-nodes")||
                path.contains("course/upload")||
                path.contains("search/")){
            return chain.filter(exchange);
        }
        //获取请求头中的token
        String token = request.getHeaders().getFirst("Authorization");
        //验证token的有效性
        Boolean verifyToken = JwtUtils.verifyToken(token);
        //如果失效，返回响应401
        if (!verifyToken) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //如果有效，放行
        //获取token中的值
        Claims claims = JwtUtils.parserToken(token).getBody();
        Long userId = claims.get("userId", Long.class);
        Long companyId = claims.get("companyId", Long.class);
        String name = claims.get("companyName", String.class);
        //构造java对象
        AuthInfo info=new AuthInfo();
        info.setUid(userId);
        info.setCompanyId(companyId);
        info.setCompanyName(name);
        //写入到请求头中
        String json = URLEncoder.encode(JSON.toJSONString(info),"UTF-8");
        ServerHttpRequest httpRequest = request.mutate().headers(httpHeaders -> {
            httpHeaders.set("payload", json);
        }).build();
        exchange.mutate().request(httpRequest);
        return chain.filter(exchange);
    }

    @Override
    //过滤器优先级
    public int getOrder() {
        return 0;
    }

}
